<template>
  <div class="resizable-layout">
    <!-- 左侧面板 -->
    <div 
      class="left-panel"
      :style="{ width: leftWidth + 'px' }"
    >
      <slot name="left"></slot>
      
      <!-- 拖拽手柄 -->
      <div 
        :style="{ width: (handleWidth || 1) + 'px' }"
        class="resize-handle"
        @mousedown="startDrag"
        :class="{ 'dragging': isDragging }"
      ></div>
    </div>
    
    <!-- 右侧面板 -->
    <div 
      class="right-panel"
      :style="{ width: `calc(100% - ${leftWidth}px)` }"
    >
      <slot name="right"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onUnmounted } from 'vue'

interface Props {
  defaultWidth?: number
  minWidth?: number
  maxWidth?: number
  handleWidth?: number
  handleColor?: string
  handleHoverColor?: string
  handleActiveColor?: string
}

const props = withDefaults(defineProps<Props>(), {
  defaultWidth: 240,
  minWidth: 180,
  maxWidth: 400,
  handleWidth: 1,
  handleColor: '#DCDFE6',
  handleHoverColor: '#c0c0c0',
  handleActiveColor: '#a0a0a0'
})

const emit = defineEmits<{
  resize: [width: number]
}>()

// 拖拽状态
const isDragging = ref(false)
const startX = ref(0)
const startWidth = ref(0)
const leftWidth = ref(props.defaultWidth)

// 开始拖拽
const startDrag = (event: MouseEvent) => {
  isDragging.value = true
  startX.value = event.clientX
  startWidth.value = leftWidth.value
  
  document.addEventListener('mousemove', handleDrag)
  document.addEventListener('mouseup', stopDrag)
  
  event.preventDefault()
}

// 拖拽中
const handleDrag = (event: MouseEvent) => {
  if (!isDragging.value) return
  
  const deltaX = event.clientX - startX.value
  const newWidth = Math.max(
    props.minWidth, 
    Math.min(props.maxWidth, startWidth.value + deltaX)
  )
  
  leftWidth.value = newWidth
  emit('resize', newWidth)
}

// 停止拖拽
const stopDrag = () => {
  isDragging.value = false
  document.removeEventListener('mousemove', handleDrag)
  document.removeEventListener('mouseup', stopDrag)
}

// 清理事件监听
onUnmounted(() => {
  document.removeEventListener('mousemove', handleDrag)
  document.removeEventListener('mouseup', stopDrag)
})

// 暴露方法
defineExpose({
  setWidth: (width: number) => {
    leftWidth.value = Math.max(props.minWidth, Math.min(props.maxWidth, width))
  },
  getWidth: () => leftWidth.value
})
</script>

<style scoped>
.resizable-layout {
  display: flex;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.left-panel {
  position: relative;
  flex-shrink: 0;
  overflow: hidden;
}

.right-panel {
  flex: 1;
  overflow: hidden;
}

.resize-handle {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: v-bind((handleWidth || 1) + 'px');
  background: v-bind(handleColor);
  cursor: col-resize;
  z-index: 10;
  transition: background-color 0.2s;
  user-select: none;
}

.resize-handle:hover {
  background: v-bind(handleHoverColor);
}

.resize-handle:active,
.resize-handle.dragging {
  background: v-bind(handleActiveColor);
}

/* 拖拽时禁用文本选择 */
.left-panel {
  user-select: none;
}

/* 拖拽时显示拖拽光标 */
.left-panel:has(.resize-handle:hover) {
  cursor: col-resize;
}
</style> 
